package info.brenstar.boxedin.sprites;

import info.brenstar.boxedin.collisions.CollisionChecker;
import info.brenstar.boxedin.core.Controllable;
import info.brenstar.boxedin.core.GravitySprite;
import info.brenstar.boxedin.core.Sprite;
import info.brenstar.boxedin.core.Updated;
import info.brenstar.boxedin.rooms.*;

import java.io.InputStream;

import org.newdawn.slick.*;
import org.newdawn.slick.geom.*;
import org.newdawn.slick.util.ResourceLoader;

public final class Player extends GravitySprite implements Updated, Controllable {
	
	private boolean grounded = false;
	
	public Player(float x, float y) {
		super(x, y);
		this.collide = true;
		this.resource = "res/player.png";
		this.gravity_direction = 270.0;
		this.gravity_max = 9;
		this.delta_gravity = 0.4;
	}
	
	@Override
	public void update() {
		/*Rectangle rect = new Rectangle(bounding_box.getX() + Trig.lendir_x(bounding_box.getWidth(), gravity_direction),
									   bounding_box.getY() + Trig.lendir_y(bounding_box.getHeight(), gravity_direction),
									   bounding_box.getX() + Trig.lendir_x(bounding_box.getWidth(), gravity_direction),
									   bounding_box.getY() + Trig.lendir_y(bounding_box.getHeight(), gravity_direction),*/
		if (!grounded) {
			Rectangle rect = new Rectangle(x, y + 33, 30, gravity == 0.0 ? 1 : (float)Math.abs(gravity));
			Sprite ground = CollisionChecker.getSpriteAt(rect);
			if (ground == null) {
				applyGravity();
			} else {
				
				if (gravity > 0.0) {
					y = ground.getY() - 32;
					grounded = true;
				} else {
					y = ground.getY() + 33;
				}
				gravity = 0.0;
			}
		}
		((TestRoom)room).getMap().update(this);
	}
	
	@Override
	public void pollKeys(Input input) {
		int move = 0;
		
		if (input.isKeyDown(Input.KEY_LEFT)) {
			move = -4;
			if (grounded) { checkGround(); }
		}
		if (input.isKeyDown(Input.KEY_RIGHT)) {
			move = 4;
			if (grounded) { checkGround(); }
		}
		
		if (move != 0) {
			Rectangle rect = new Rectangle(x + (move > 0 ? 33 : move), y, Math.abs(move), 31);
			Sprite sprite = room.collidesWith(rect);
			if (sprite == null) {
				x += move;
			} else {
				//snap-to
				float px = sprite.getX();
				if (x < px) {
					x = px - 32;
				} else {
					x = px + 33;
				}
				
			}
		}
		
		if (input.isKeyDown(Input.KEY_UP)) {
			if (grounded) {
				gravity = -8;
				grounded = false;
			}
		}
		
		((TestRoom)room).getMap().update(this);
	}
	
	@Override
	public void render(Graphics g) {
		g.drawImage(image, x, y);
		
	}

	@Override
	public void init() {
		if (ResourceLoader.resourceExists(resource)) {
			InputStream stream = ResourceLoader.getResourceAsStream(resource);
			try {
				this.image = new Image(stream, resource, false);
			} catch (SlickException e) {}
		} else {
			try {
				this.image = new Image(32, 32);
			} catch (SlickException e) {
			}
		}
	}

	@Override
	public void unload() {
		if (!image.isDestroyed()) {
			try {
				image.destroy();
			} catch (SlickException e) {}
		}
		
	}

	@Override
	public void kill() {
		unload();
	}
	
	public void checkGround() {
		Rectangle rect = new Rectangle(x, 33 + y, 32, gravity == 0.0 ? 1 : (float)gravity);
		Sprite ground = room.collidesWith(rect);
		grounded = ground != null;
	}
	
	
}
